home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / upc12bs1.zip / UUCP / uustat.c < prev    next >
C/C++ Source or Header  |  1993-10-03  |  38KB  |  1,091 lines

  1. /*--------------------------------------------------------------------*/
  2. /*    u u s t a t . c                                                 */
  3. /*                                                                    */
  4. /*    Job status report for UUPC/extended                             */
  5. /*                                                                    */
  6. /*                                                                    */
  7. /*    Copyright 1988 (C), Dewey Coffman                               */
  8. /*    Changes Copyright 1991 (C), Andrew H. Derbyshire                */
  9. /*--------------------------------------------------------------------*/
  10.  
  11. /*--------------------------------------------------------------------*/
  12. /*         System include files                                       */
  13. /*--------------------------------------------------------------------*/
  14.  
  15. #include <stdio.h>
  16. #include <io.h>
  17. #include <sys/types.h>
  18. #include <sys/stat.h>
  19. #include <string.h>
  20. #include <time.h>
  21. #include <fcntl.h>
  22. #include <stdlib.h>
  23.  
  24. /*--------------------------------------------------------------------*/
  25. /*         Local include files                                        */
  26. /*--------------------------------------------------------------------*/
  27.  
  28. #include "lib.h"
  29. #include "dater.h"
  30. #include "export.h"
  31. #include "getopt.h"
  32. #include "getseq.h"
  33. #include "hlib.h"
  34. #include "hostable.h"
  35. #include "hostatus.h"
  36. #include "import.h"
  37. #include "pushpop.h"
  38. #include "readnext.h"
  39. #include "security.h"
  40. #include "stater.h"
  41. #include "timestmp.h"
  42.  
  43. #define DAY (60l * 60l * 24l)
  44. #define ALL    "all"
  45. #define MAXL      128      // MAX LINE LENGTH
  46.  
  47. #define STRCREAT(s, s2, s3)\
  48.    strcpy(s, s2);\
  49.    strcat(s, s3);\
  50.  
  51. /*--------------------------------------------------------------------*/
  52. /*                          Local data types                          */
  53. /*--------------------------------------------------------------------*/
  54.  
  55. typedef enum {
  56.       POLL_CALL = 'P',
  57.       RECEIVE_CALL = 'R',
  58.       SEND_CALL = 'S'
  59.       } CALLTYPE;
  60.  
  61.  
  62. struct data_queue {
  63.    char name[FILENAME_MAX];
  64.    struct data_queue *next_link;
  65.    time_t created;
  66.    long size;
  67.    boolean execute;
  68.    char type;
  69. } ;
  70.  
  71. /*--------------------------------------------------------------------*/
  72. /*                             Verb list                              */
  73. /*--------------------------------------------------------------------*/
  74.  
  75. typedef enum {
  76.    LIST_DEFAULT = 1,
  77.    LIST_ALL,
  78.    LIST_ACCESS,
  79.    LIST_QUEUE,
  80.    KILL_JOB,
  81.    REFRESH_JOB,
  82.    FORCE_POLL
  83.    } COMMAND_CLASS;
  84.  
  85. /*--------------------------------------------------------------------*/
  86. /*                Processing to be taken by open_call                 */
  87. /*--------------------------------------------------------------------*/
  88.  
  89. typedef enum {
  90.    JOB_STATUS = 1,
  91.    JOB_KILL,
  92.    JOB_REFRESH
  93.    } CALL_ACTION;
  94.  
  95. /*--------------------------------------------------------------------*/
  96. /*                          Global variables                          */
  97. /*--------------------------------------------------------------------*/
  98.  
  99. currentfile();
  100.  
  101. static const char *host_status[] = {
  102.       "(invalid - entry not properly initialized)",
  103.       "(local host system)",
  104.       "(host for gateway purposes only)",
  105.       "Never called",
  106.       "Dialing now",
  107.       "Invalid device or speed in SYSTEMS file",
  108.       "Device not available",
  109.       "Conversation start-up failed",
  110.       "Talking",
  111.       "Callback required",
  112.       "Modem initialization script failed",
  113.       "Dial failed",
  114.       "Script failed",
  115.       "Max retry reached",
  116.       "Retry time not reached",
  117.       "Call succeeded",
  118.       "Wrong machine name",
  119.       "Unknown host",
  120.       "Failed",
  121.       "Wrong time to call",
  122.       "(call successed, entry not reset)",
  123.    } ;
  124.  
  125. /*--------------------------------------------------------------------*/
  126. /*                        Internal prototypes                         */
  127. /*--------------------------------------------------------------------*/
  128.  
  129. static void all( const char *system, const char *userid );
  130.  
  131. static char *is_job(const char *jobid );
  132.  
  133. static void kill_job(const char *s);
  134.  
  135. static void long_stats( const char *system );
  136.  
  137. static void short_stats( const char *system );
  138.  
  139. static CALLTYPE open_call( const char *callname,
  140.                            const char *remote,
  141.                                  struct data_queue **current,
  142.                                  char *user,
  143.                                  char *sys,
  144.                            const CALL_ACTION action);
  145.  
  146. static void open_data(const char *file,
  147.                             char *user,
  148.                             char *sys,
  149.                             char *command);
  150.  
  151. static void poll(const char *callee);
  152.  
  153. static void print_all(       char *job,
  154.                        struct data_queue *current,
  155.                        const char *user,
  156.                        const char *sys);
  157.  
  158. static void refresh_job(const char *s);
  159.  
  160. static void touch( const char *fname );
  161.  
  162. static void usage( void );
  163.  
  164. /*--------------------------------------------------------------------*/
  165. /*    m a i n                                                         */
  166. /*                                                                    */
  167. /*    main program                                                    */
  168. /*--------------------------------------------------------------------*/
  169.  
  170. void main(int  argc, char  **argv)
  171. {
  172.    int c;
  173.    extern char *optarg;
  174.    extern int   optind;
  175.    COMMAND_CLASS command = LIST_DEFAULT;
  176.  
  177.    char *system = NULL;
  178.    char *userid = NULL;
  179.    char *job    = NULL;
  180.  
  181. /*--------------------------------------------------------------------*/
  182. /*     Report our version number and date/time compiled               */
  183. /*--------------------------------------------------------------------*/
  184.  
  185.    debuglevel = 0;
  186.    banner( argv );
  187.  
  188. #if defined(__CORE__)
  189.    copywrong = strdup(copyright);
  190.    checkref(copywrong);
  191. #endif
  192.  
  193.    if (!configure( B_UUSTAT ))
  194.       exit(1);   /* system configuration failed */
  195.  
  196. /*--------------------------------------------------------------------*/
  197. /*                   Switch to the spool directory                    */
  198. /*--------------------------------------------------------------------*/
  199.  
  200.    tzset();                      // Set up time zone information
  201.    PushDir( E_spooldir );
  202.    atexit( PopDir );
  203.  
  204. /*--------------------------------------------------------------------*/
  205. /*        Process our arguments                                       */
  206. /*--------------------------------------------------------------------*/
  207.  
  208.    while ((c = getopt(argc, argv, "amqk:r:s:u:x:P:")) !=  EOF)
  209.       switch(c) {
  210.       case 'a':
  211.          command = LIST_ALL;
  212.          break;
  213.  
  214.       case 'm':
  215.          command = LIST_ACCESS;
  216.          system = optarg;
  217.          break;
  218.  
  219.       case 'q':
  220.          command = LIST_QUEUE;
  221.          break;
  222.  
  223.       case 'k':
  224.          command = KILL_JOB;
  225.          job = optarg;
  226.          break;
  227.  
  228.       case 'r':
  229.          command = REFRESH_JOB;
  230.          job = optarg;
  231.          break;
  232.  
  233.       case 's':
  234.          if ( system != NULL )
  235.          {
  236.             printmsg(0,"Invalid or duplicate option -s %s",optarg);
  237.             usage();
  238.          }
  239.          system = optarg;
  240.          break;
  241.  
  242.       case 'u':
  243.          userid = optarg;
  244.          break;
  245.  
  246.       case 'x':
  247.          debuglevel = atoi( optarg );
  248.          break;
  249.  
  250.       case 'P':
  251.          command = FORCE_POLL;
  252.          if ( system != NULL )
  253.          {
  254.             printmsg(0,"Invalid or duplicate option -P %s",optarg);
  255.             usage();
  256.          }
  257.          system = optarg;
  258.          break;
  259.  
  260.       case '?':
  261.          usage();
  262.    }
  263.  
  264.    if (optind != argc) {
  265.       puts("Extra parameter(s) at end.");
  266.       exit(2);
  267.    }
  268.  
  269. /*--------------------------------------------------------------------*/
  270. /*                 Determine if we have a valid host                  */
  271. /*--------------------------------------------------------------------*/
  272.  
  273.    if( (system != NULL) && !equal( system , ALL ) )
  274.    {
  275.       struct HostTable *hostp = checkreal( system );
  276.  
  277.       if (hostp  ==  BADHOST)
  278.       {
  279.          printf("Unknown host \"%s\", program terminating.\n",
  280.                system );
  281.          panic();
  282.       }
  283.    } /* if */
  284.  
  285. /*--------------------------------------------------------------------*/
  286. /*                   Execute the requested command                    */
  287. /*--------------------------------------------------------------------*/
  288.  
  289.    switch ( command )
  290.    {
  291.       case LIST_DEFAULT:
  292.          if ( (system == NULL ) && ( userid == NULL) )
  293.          {
  294.             all( ALL, E_mailbox );
  295.             break;
  296.          }
  297.             /* Otherwise, fall through ... */
  298.  
  299.       case LIST_ALL:
  300.          if ( system == NULL )
  301.             system = ALL;
  302.          if ( userid == NULL )
  303.             userid = ALL;
  304.          all( system, userid );
  305.          break;
  306.  
  307.       case LIST_ACCESS:
  308.          if ( system == NULL )
  309.             system = ALL;
  310.          short_stats( system );
  311.          break;
  312.  
  313.       case LIST_QUEUE:
  314.          if ( system == NULL )
  315.             system = ALL;
  316.          long_stats( system );
  317.          break;
  318.  
  319.       case KILL_JOB:
  320.          kill_job( job );
  321.          break;
  322.  
  323.       case REFRESH_JOB:
  324.          refresh_job( job );
  325.          break;
  326.  
  327.       case FORCE_POLL:
  328.          poll( system );
  329.          break;
  330.  
  331.       default:
  332.          panic();
  333.  
  334.    } /* switch */
  335.    exit(0);
  336.  
  337. } /* main */
  338.  
  339. /*--------------------------------------------------------------------*/
  340. /*    a l l                                                           */
  341. /*                                                                    */
  342. /*    Report on all systems                                           */
  343. /*--------------------------------------------------------------------*/
  344.  
  345. void all( const char *system, const char *userid)
  346. {
  347.    char  canon[FILENAME_MAX];
  348.    long  size, ltime;
  349.    struct HostTable *hostp;
  350.    boolean hit = FALSE;
  351.  
  352.    if ( equal(system,ALL) )
  353.       hostp = nexthost( TRUE );
  354.    else
  355.       hostp = checkreal( system );
  356.  
  357. /*--------------------------------------------------------------------*/
  358. /*                  Scan one or all host directories                  */
  359. /*--------------------------------------------------------------------*/
  360.  
  361.    while  (hostp !=  BADHOST )
  362.    {
  363.       char fname[FILENAME_MAX];
  364.  
  365. /*--------------------------------------------------------------------*/
  366. /*   Examine all of the files in the spool directory for this host    */
  367. /*--------------------------------------------------------------------*/
  368.  
  369.       while( readnext(fname , hostp->hostname, "C", NULL, <ime, &size) )
  370.       {
  371.          boolean display = equali( userid, ALL );
  372.          struct data_queue *data_link = NULL;
  373.          char user[MAXL];
  374.          char sys[MAXL];
  375.  
  376.          strcpy(user,userid);       // Nice default for the user
  377.                                     /* Generates more output if
  378.                                        straight copies in the queue  */
  379.          strcpy(sys, E_nodename);   // Nice default for node as well
  380.  
  381.          printmsg(1,"ALL(%s)", fname);
  382.          exportpath(canon, fname, hostp->hostname);
  383.  
  384. /*--------------------------------------------------------------------*/
  385. /*               Determine what kind of Call file it is               */
  386. /*--------------------------------------------------------------------*/
  387.  
  388.          switch(open_call(fname, hostp->hostname,
  389.                            &data_link, user, sys, JOB_STATUS))
  390.          {
  391.             case POLL_CALL:
  392.                if ( display )
  393.                {
  394.                   hit = TRUE;
  395.                   printf( "%s %s %s\n",canon+2,dater(ltime, NULL),
  396.                         "(POLL)");
  397.                }
  398.                break;
  399.  
  400.             case SEND_CALL:
  401.             case RECEIVE_CALL:
  402.                if( equal(userid , ALL) || equali(userid, user))
  403.                   display = TRUE;
  404.  
  405.                if(display)
  406.                {
  407.                    hit = TRUE;
  408.                    print_all( canon + 2, data_link, user,
  409.                               hostp->hostname );
  410.                }
  411.                break;
  412.          } /* switch */
  413.  
  414.       } /* while */
  415.  
  416. /*--------------------------------------------------------------------*/
  417. /*    If processing all hosts, step to the next host in the queue     */
  418. /*--------------------------------------------------------------------*/
  419.  
  420.       if( equal( system , ALL ))
  421.          hostp = nexthost( FALSE );
  422.       else
  423.          hostp = BADHOST;
  424.  
  425.    } /* while */
  426.  
  427.    if ( !hit )
  428.       printf("uustat: No jobs queued for system %s by user %s\n",
  429.                system , userid );
  430.  
  431. } /* all */
  432.  
  433. /*--------------------------------------------------------------------*/
  434. /*    p o l l                                                         */
  435. /*                                                                    */
  436. /*    Write a dummy call file to request a poll of a host             */
  437. /*--------------------------------------------------------------------*/
  438.  
  439. static void poll(const char *callee)
  440. {
  441.  
  442.    char tmfile[15];           // Call file, UNIX format name
  443.    char msname[FILENAME_MAX];
  444.    FILE *stream;
  445.    static char *spool_fmt = SPOOLFMT;              // spool file name
  446.    struct HostTable *hostp;
  447.  
  448. /*--------------------------------------------------------------------*/
  449. /*              Determine first (only?) host to process               */
  450. /*--------------------------------------------------------------------*/
  451.  
  452.    if ( equal(callee,ALL) )
  453.       hostp = nexthost( TRUE );
  454.    else
  455.       hostp = checkreal( callee );
  456.  
  457. /*--------------------------------------------------------------------*/
  458. /*                  Scan one or all host directories                  */
  459. /*--------------------------------------------------------------------*/
  460.  
  461.    while  (hostp !=  BADHOST )
  462.    {
  463.       printmsg(1,"POLL(%s)", hostp->hostname);
  464.       sprintf(tmfile,"%.8s",hostp->hostname);
  465.  
  466.       if ( ValidDOSName( tmfile, FALSE ) || !equal(callee, ALL))
  467.       {
  468.          sprintf(tmfile, spool_fmt, 'C', hostp->hostname,'Z' ,
  469.                   "000");
  470.          importpath( msname, tmfile, hostp->hostname);
  471.  
  472.          if ( access( msname , 0 ))   // Does the host file exist?
  473.          {
  474.             stream = FOPEN( msname ,"w", BINARY_MODE);
  475.  
  476.             if ( stream == NULL )
  477.             {
  478.                printerr( msname );
  479.                printmsg(0,"uustat: problem creating poll file %s (%s)",
  480.                         tmfile, msname);
  481.                panic();
  482.             }
  483.  
  484.             fclose( stream );
  485.  
  486.             printmsg(0,"Created dummy job %s (%s) for system %s",
  487.                   tmfile, msname, hostp->hostname );
  488.  
  489.          } /* if */
  490.          else
  491.             printmsg(0,"Dummy job %s (%s) already exists for system %s",
  492.                   tmfile, msname, hostp->hostname );
  493.  
  494.       } /* if ( ValidDOSName( tmfile ) || !equal(callee, ALL)) */
  495.       else {
  496.          printmsg(0,"%s is not a valid host name, skipping",
  497.                      hostp->hostname);
  498.       } /* else */
  499.  
  500. /*--------------------------------------------------------------------*/
  501. /*    If processing all hosts, step to the next host in the queue     */
  502. /*--------------------------------------------------------------------*/
  503.  
  504.       if( equal( callee , ALL ))
  505.          hostp = nexthost( FALSE );
  506.       else
  507.          hostp = BADHOST;
  508.  
  509.    } /* while  (hostp !=  BADHOST ) */
  510.  
  511. } /* poll */
  512.  
  513.  
  514. /*--------------------------------------------------------------------*/
  515. /*    l o n g _ s t a t s                                             */
  516. /*                                                                    */
  517. /*    Report full information on jobs for a host                      */
  518. /*--------------------------------------------------------------------*/
  519.  
  520. /*--------------------------------------------------------------------*/
  521. /* fifi      1C     03/30-16:34 LOGIN FAILED Retry: 22:39 Count: 130  */
  522. /* helps     2C     03/30-16:32 SUCCESSFUL                            */
  523. /* im4u      5C(1)  03/30-06:50 LOGIN FAILED Retry: 11:15 Count: 9    */
  524. /* irasun           03/30-16:23 TALKING                               */
  525. /* killer    5C(6)  03/29-11:13 WRONG TIME TO CALL                    */
  526. /* radian    18C    03/30-16:42 WRONG TIME TO CALL                    */
  527. /* shemp      1C    03/30-14:43 LOGIN FAILED Retry: 20:48 Count: 107  */
  528. /* unisec     2C(1) 03/30-16:50 WRONG TIME TO CALL                    */
  529. /* ut-emx     1X    03/30-16:50 SUCCESSFUL                            */
  530. /*--------------------------------------------------------------------*/
  531.  
  532. static void long_stats( const char *system )
  533. {
  534.    struct HostTable *hostp;
  535.    time_t now = time( NULL );
  536.    boolean hit = FALSE;
  537.    time_t ltime;
  538.    long size;
  539.    char buf[BUFSIZ];
  540.  
  541.    HostStatus();              // Load the host status table info
  542.  
  543. /*--------------------------------------------------------------------*/
  544. /*                  Get the first system to process                   */
  545. /*--------------------------------------------------------------------*/
  546.  
  547.    if ( equal(system,ALL) )
  548.       hostp = nexthost( TRUE );
  549.    else
  550.       hostp = checkreal( system );
  551.  
  552. /*--------------------------------------------------------------------*/
  553. /*              Begin loop to display status of systems               */
  554. /*--------------------------------------------------------------------*/
  555.  
  556.    while(hostp != BADHOST )
  557.    {
  558.       char fname[FILENAME_MAX];
  559.                               // Get list of files in the directory
  560.       size_t jobs = 0;        // Declare, reset counter
  561.       time_t oldest_file = now;  // Make the "oldest" file new
  562.  
  563. /*--------------------------------------------------------------------*/
  564. /*           Inner loop to count files and determine oldest           */
  565. /*--------------------------------------------------------------------*/
  566.  
  567.       while( readnext(fname, hostp->hostname, "C", NULL, <ime, &size) != NULL )
  568.       {
  569.          if ((ltime > -1) && (ltime < oldest_file ))
  570.             oldest_file = ltime;
  571.  
  572.          jobs++;
  573.  
  574.       } /* while */
  575.  
  576. /*--------------------------------------------------------------------*/
  577. /*  We have all the information for this system; summary and display  */
  578. /*--------------------------------------------------------------------*/
  579.  
  580.       if ( jobs > 0 )
  581.       {
  582.          if (oldest_file + DAY < now)     // File older than 24 hours?
  583.             sprintf( buf , "(%d)", (now - oldest_file) / DAY );
  584.                                           // Yes --> Format info
  585.          else
  586.             *buf = '\0';                  // No --> No, empty display
  587.  
  588.          printf("%-8.8s  %3dC%-4s  %s  %s\n", hostp->hostname, jobs , buf,
  589.                dater( hostp->hstats->lconnect , NULL ),
  590.                hostp->hstatus < last_status ?
  591.                      host_status[ hostp->hstatus ] :
  592.                      "*** INVALID/UNDOCUMENTED STATUS ***");
  593.          hit = TRUE;
  594.  
  595.       } /* if ( jobs > 0 ) */
  596.  
  597.       if (equal(system, ALL))
  598.          hostp = nexthost( FALSE );
  599.       else
  600.          hostp = BADHOST;
  601.    } /* while */
  602.  
  603.    if ( !hit )
  604.       printf("uustat: No jobs queued for system %s\n", system );
  605. } /* long_stats */
  606.  
  607. /*--------------------------------------------------------------------*/
  608. /*    s h o r t _ s t a t s                                           */
  609. /*                                                                    */
  610. /*    Report access to a system                                       */
  611. /*--------------------------------------------------------------------*/
  612.  
  613. static void short_stats( const char *system )
  614. {
  615.    struct HostTable *hostp;
  616.  
  617.    HostStatus();              // Load the host status table info
  618.  
  619. /*--------------------------------------------------------------------*/
  620. /*                  Get the first system to process                   */
  621. /*--------------------------------------------------------------------*/
  622.  
  623.    if ( equal(system,ALL) )
  624.       hostp = nexthost( TRUE );
  625.    else
  626.       hostp = checkreal( system );
  627.  
  628. /*--------------------------------------------------------------------*/
  629. /*              Begin loop to display status of systems               */
  630. /*--------------------------------------------------------------------*/
  631.  
  632.    while(hostp != BADHOST )
  633.    {
  634.       printf("%-8.8s  %s  %s\n", hostp->hostname,
  635.             dater( hostp->hstats->lconnect , NULL ),
  636.             hostp->hstatus < last_status ?
  637.                   host_status[ hostp->hstatus ] :
  638.                   "*** INVALID/UNDOCUMENTED STATUS ***");
  639.  
  640.       if (equal(system, ALL))
  641.          hostp = nexthost( FALSE );
  642.       else
  643.          hostp = BADHOST;
  644.    } /* while */
  645.  
  646. } /* short_stats */
  647.  
  648.  
  649. /*--------------------------------------------------------------------*/
  650. /*    k i l l _ j o b                                                 */
  651. /*                                                                    */
  652. /*    Kill a queued UUPC/extended job                                 */
  653. /*--------------------------------------------------------------------*/
  654.  
  655. static void kill_job(const char *jobid)
  656. {
  657.    char *system;              // System name returned by is_job()
  658.    char host[FILENAME_MAX];
  659.    char canon[FILENAME_MAX];
  660.    char user[FILENAME_MAX];
  661.    char sys[FILENAME_MAX];
  662.  
  663.    strcpy(canon,"C.");
  664.    strcat(canon,jobid);
  665.    strcpy( user, "uucp");
  666.    system = is_job( canon ); // Never returns if an error occurs
  667.    importpath( host, canon, system );
  668.                               // Get the local name of the file
  669.    open_call(host, system, NULL, user, sys, JOB_KILL);
  670.    unlink( host );
  671.    printf("Deleted file %s (%s)\n", canon, host);
  672.    printf("Killed job %s (%s) queued for host %s by %s\n",
  673.             jobid, host, system, user);
  674.  
  675. } /* kill_job */
  676.  
  677. /*--------------------------------------------------------------------*/
  678. /*    r e f r e s h _ j o b                                           */
  679. /*                                                                    */
  680. /*    Refresh a job in the spool                                      */
  681. /*--------------------------------------------------------------------*/
  682.  
  683. static void refresh_job(const char *jobid)
  684. {
  685.    char *system;              // System name returned by is_job()
  686.    char host[FILENAME_MAX];
  687.    char canon[FILENAME_MAX];
  688.    char user[FILENAME_MAX];
  689.    char sys[FILENAME_MAX];
  690.  
  691.    strcpy(canon,"C.");
  692.    strcat(canon,jobid);
  693.    strcpy( user, "uucp");
  694.    system = is_job( canon ); // Never returns if an error occurs
  695.    importpath( host, canon, system );
  696.                               // Get the local name of the file
  697.    open_call(host, system, NULL, user, sys, JOB_REFRESH);
  698.    touch( host );
  699.    printf("Rejuvenated job %s (%s) queued for host %s by %s\n",
  700.             jobid, host, system, user);
  701.  
  702. } /* refresh_job */
  703.  
  704. /*--------------------------------------------------------------------*/
  705. /*    o p e n _ c a l l                                               */
  706. /*                                                                    */
  707. /*    Process a call file                                             */
  708. /*--------------------------------------------------------------------*/
  709.  
  710. static CALLTYPE open_call( const char *callname,
  711.                            const char *remote,
  712.                                  struct data_queue **top,
  713.                                  char *user,
  714.                                  char *sys,
  715.                            const CALL_ACTION action )
  716. {
  717.    FILE *stream;
  718.    char buf[BUFSIZ];
  719.    struct data_queue *current = NULL;
  720.    CALLTYPE this_call = POLL_CALL;
  721.  
  722.    char host[FILENAME_MAX];
  723.    char type[FILENAME_MAX], fname[FILENAME_MAX], tname[FILENAME_MAX];
  724.    char flgs[FILENAME_MAX], dname[FILENAME_MAX];
  725.  
  726. /*--------------------------------------------------------------------*/
  727. /*                    Open the file for processing                    */
  728. /*--------------------------------------------------------------------*/
  729.  
  730.    printmsg(2,"Scanning call file \"%s\"", callname );
  731.    stream = FOPEN( callname, "r",TEXT_MODE );
  732.  
  733.    if ( stream == NULL )
  734.    {
  735.       printerr( callname );
  736.       panic();
  737.    }
  738.  
  739.    while( fgets( buf, BUFSIZ, stream) != NULL)
  740.    {
  741.       switch (*buf)
  742.       {
  743.          case '#':
  744.             break;
  745.  
  746.          case 'S':
  747.          case 'R':
  748.             *dname = '\0';
  749.             sscanf(buf, "%s %s %s %s %s %s",
  750.                          type, fname, tname, user , flgs, dname);
  751.             this_call = *type;
  752.  
  753.             if ( ! strlen( dname ) )
  754.             {
  755.                printmsg(0,"Invalid data in call file \"%s\"",callname);
  756.                panic();
  757.             }
  758.  
  759. /*--------------------------------------------------------------------*/
  760. /*    If returning job status, allocate next link in status queue     */
  761. /*--------------------------------------------------------------------*/
  762.  
  763.             if ( action == JOB_STATUS )
  764.             {
  765.               if ( current == NULL)
  766.                  *top = current = malloc( sizeof *current );
  767.               else {
  768.                  current->next_link = malloc( sizeof *current );
  769.                  current = current->next_link;
  770.               }
  771.               checkref( current );
  772.  
  773.               current->next_link = NULL;
  774.               current->type      = *buf;
  775.             } /* action */
  776.  
  777. /*--------------------------------------------------------------------*/
  778. /*    Get the UNIX and local filenames for data file to be            */
  779. /*    processed; we always report the original file name, but we      */
  780. /*    always look at and/or update the spool copy of the data; we     */
  781. /*    never alter or delete the original                              */
  782. /*--------------------------------------------------------------------*/
  783.  
  784.             if ( this_call == SEND_CALL )
  785.             {
  786.                time_t created;
  787.                long size;
  788.  
  789.                if (equal(dname, "D.0"))
  790.                   strcpy( host, fname );
  791.                else
  792.                   importpath( host, dname, remote );
  793.  
  794.                created   = stater( host,  &size);
  795.  
  796.                switch  ( action )
  797.                {
  798.                   case JOB_STATUS:
  799.                      current->created = created;
  800.                      current->size    = size;
  801.  
  802.                      if ((created != -1) &&
  803.                          (equaln(tname ,"X.",2)))  // Execute file?
  804.                      {
  805.                         open_data( host, user, sys, current->name );
  806.                         current->execute = TRUE;
  807.                      }
  808.                      else {
  809.                         current->execute = FALSE;
  810.                         strcpy( current->name , fname );
  811.                      }
  812.                      break;
  813.  
  814.                   case JOB_KILL:
  815.                      if ((created != -1) && !equal(dname, "D.0"))
  816.                      {
  817.                         unlink( host );
  818.                         printf("Deleted file %s (%s)\n", dname, host);
  819.                      }
  820.                      break;
  821.  
  822.                   case JOB_REFRESH:
  823.                      if ((created != -1) && !equal(dname, "D.0"))
  824.                         touch( host );
  825.                      break;
  826.  
  827.                   default:
  828.                      panic();
  829.                } /* switch */
  830.             }
  831.             else if ( action == JOB_STATUS )
  832.             {
  833.                current->execute = FALSE;
  834.                strcpy( current->name , fname );
  835.                current->created = stater( callname, ¤t->size);
  836.             }
  837.  
  838.             break;
  839.  
  840.          default:
  841.             printmsg(0,"Invalid line \"%s\" in call file \"%s\"",
  842.                               buf, callname);
  843.             break;
  844.       } /* switch */
  845.    } /* while */
  846.  
  847. /*--------------------------------------------------------------------*/
  848. /*                   Clean up and return to caller                    */
  849. /*--------------------------------------------------------------------*/
  850.  
  851.    if (ferror( stream ))
  852.    {
  853.       printerr( callname );
  854.       clearerr( stream );
  855.    }
  856.  
  857.    fclose( stream );
  858.    return this_call;
  859.  
  860. } /* open call */
  861.  
  862.  
  863. /*--------------------------------------------------------------------*/
  864. /*    o p e n _ d a t a                                               */
  865. /*                                                                    */
  866. /*    Process a single execute file                                   */
  867. /*--------------------------------------------------------------------*/
  868.  
  869. static void open_data(const char *file,
  870.                       char *user,
  871.                       char *sys,
  872.                       char *command)
  873. {
  874.    FILE  *data_fp;
  875.    char  data_buf[BUFSIZ];
  876.    char  *token = "(none)";
  877.    static char f_name[ FILENAME_MAX ];
  878.    size_t  bytes = 0;
  879.  
  880.    printmsg(1,"INSIDE OPEN_DATA(%s)",file);
  881.    *f_name = '\0';
  882.  
  883.    printmsg(1,"OPENING(%s)",file);
  884.    data_fp = FOPEN(file, "r", BINARY_MODE);
  885.    if(data_fp ==  NULL){
  886.       printerr( file );
  887.       panic();
  888.    }
  889.    printmsg(1,"OPEN (%s) SIZE (%d)", file, BUFSIZ);
  890.  
  891.    while(fgets(data_buf, (int) BUFSIZ, data_fp) !=  NULL){
  892.  
  893.       size_t len = strlen( data_buf );
  894.       bytes += strlen( data_buf );
  895.       if ( data_buf[ --len ] == '\n')
  896.          data_buf[ len ] = '\0';
  897.  
  898. /*--------------------------------------------------------------------*/
  899. /*                 Determine what kind of line it is                  */
  900. /*--------------------------------------------------------------------*/
  901.  
  902.       switch(data_buf[0]){
  903.          case '#':
  904.          printmsg(5,"COMMENT %s", data_buf);
  905.             break;
  906.  
  907.           case 'U':
  908.             token = strtok( data_buf + 1, WHITESPACE );
  909.             if ( token == NULL )
  910.                break;
  911.             strncpy( user, token , MAXL );
  912.             user[ MAXL-1 ] = '\0';
  913.             token = strtok( NULL , WHITESPACE );
  914.             if ( token == NULL )
  915.                break;
  916.             strncpy(  sys, token , MAXL);
  917.             sys[ MAXL-1 ] = '\0';
  918.             printmsg(1,"SYSTEM = (%s), USER = (%s)",sys,user);
  919.             break;
  920.  
  921.          case 'F':
  922.             printmsg(5,"File %s", data_buf);
  923.             token = strtok( data_buf + 1 , WHITESPACE );
  924.             strncpy( f_name, token , FILENAME_MAX );
  925.             f_name[ FILENAME_MAX - 1 ] = '\0';
  926.             break;
  927.  
  928.          case 'I':
  929.             printmsg(5,"Input %s", data_buf);
  930.             break;
  931.  
  932.          case 'C':
  933.             printmsg(1,"Command %s", data_buf);
  934.             token = strchr(data_buf,' ') + 1;
  935.             strncpy(command, token , FILENAME_MAX - 1);
  936.             command[ FILENAME_MAX - 1] = '\0';
  937.             break;
  938.          default:
  939.             printmsg(1,"UNKNOWN LINE %s", data_buf);
  940.             break;
  941.       } /* switch */
  942.    } /* while */
  943.  
  944.    printmsg(1,"CLOSED (%s), bytes = %d, d file = %s", file, bytes, token);
  945.    fclose(data_fp);
  946. } /* open_data */
  947.  
  948. /*--------------------------------------------------------------------*/
  949. /*    p r i n t _ a l l                                               */
  950. /*                                                                    */
  951. /*    Print all the information related to a job in the spool         */
  952. /*--------------------------------------------------------------------*/
  953.  
  954. static void print_all(       char *job,
  955.                              struct data_queue *current ,
  956.                        const char *user,
  957.                        const char *sys )
  958. {
  959.    char blanks[FILENAME_MAX];
  960.    size_t subscript = 0;
  961.  
  962. /*--------------------------------------------------------------------*/
  963. /*  Create a blank buffer for printing all of the first line of data  */
  964. /*--------------------------------------------------------------------*/
  965.  
  966.    while ( job[subscript] != '\0')
  967.       blanks[subscript++] = ' ';
  968.    blanks[ subscript ] = '\0';
  969.  
  970. /*--------------------------------------------------------------------*/
  971. /*                Loop through the files for this job                 */
  972. /*--------------------------------------------------------------------*/
  973.  
  974.    while ( current != NULL )
  975.    {
  976.       struct data_queue *save_data = current->next_link;
  977.       if ( current->execute)
  978.          printf("%s %s %c %-8.8s %-8.8s %s\n", job,
  979.                      dater( current->created, NULL ),
  980.                      current->type,
  981.                      sys, user, current->name );
  982.       else
  983.          printf("%s %s %c %-8.8s %-8.8s %ld %s\n", job,
  984.                      dater( current->created, NULL ),
  985.                      current->type,
  986.                      sys, user, current->size , current->name );
  987.  
  988.       job = blanks;           // Don't print job name more than once
  989.       free( current );        // Release the abused storage
  990.       current = save_data;
  991.    } /* while */
  992.  
  993. } /* print_all */
  994.  
  995. /*--------------------------------------------------------------------*/
  996. /*    i s _ j o b                                                     */
  997. /*                                                                    */
  998. /*    Determine if a file is a valid job                              */
  999. /*                                                                    */
  1000. /*    The task of finding a proper job made is harder by the fact     */
  1001. /*    UUPC inserts all these jobs into separate directories.  We      */
  1002. /*    brute force it, checking all known hosts for the wayward        */
  1003. /*    file.  This is relatively cheap, since most hosts will fail     */
  1004. /*    on the host name and thus we never look on disk.  Since job     */
  1005. /*    sequence numbers are global across UUPC/extende, a false hit    */
  1006. /*    on the host doesn't hurt because the job number will never      */
  1007. /*    match.                                                          */
  1008. /*--------------------------------------------------------------------*/
  1009.  
  1010. static char *is_job(const char *callfile)
  1011. {
  1012.    struct HostTable *hostp;
  1013.    char host[FILENAME_MAX];
  1014.    boolean hit = FALSE;
  1015.  
  1016. /*--------------------------------------------------------------------*/
  1017. /*                  Get the first system to process                   */
  1018. /*--------------------------------------------------------------------*/
  1019.  
  1020.       hostp = nexthost( TRUE );
  1021.  
  1022. /*--------------------------------------------------------------------*/
  1023. /*              Begin loop to display local system                    */
  1024. /*--------------------------------------------------------------------*/
  1025.  
  1026.    while(hostp != BADHOST )
  1027.    {
  1028.       if (equaln(hostp->hostname, &callfile[2],
  1029.                 min( strlen( hostp->hostname ), HOSTLEN)))
  1030.                               // Right host?
  1031.       {                       // Maybe --> Look for the file
  1032.          importpath( host, callfile, hostp->hostname);
  1033.          if ( !access( host, 0 ))   // Does the host file exist?
  1034.             return hostp->hostname; // Yes --> Return success
  1035.          hit = TRUE;
  1036.       }
  1037.  
  1038.       hostp = nexthost( FALSE );
  1039.    } /* while */
  1040.  
  1041. /*--------------------------------------------------------------------*/
  1042. /*          We didn't get the host; report an error and exit          */
  1043. /*--------------------------------------------------------------------*/
  1044.  
  1045.    if ( hit )
  1046.       printf("Unable to locate call file %s -- run uustat -a\n", callfile );
  1047.    else
  1048.       printf("Unable to locate call file %s -- hostname may be incorrect\n",
  1049.                callfile);
  1050.    exit(1);
  1051.    return NULL;                  // Make C compiler happy
  1052. } /* is_job */
  1053.  
  1054. /*--------------------------------------------------------------------*/
  1055. /*    t o u c h                                                       */
  1056. /*                                                                    */
  1057. /*    Update list modified time for a file by opening and closing it  */
  1058. /*--------------------------------------------------------------------*/
  1059.  
  1060. static void touch( const char *fname)
  1061. {
  1062.    printf("touch: function not available.  Parameter was \"%s\"\n",
  1063.             fname);
  1064. } /* touch */
  1065.  
  1066.  
  1067. /*--------------------------------------------------------------------*/
  1068. /*    u s a g e                                                       */
  1069. /*                                                                    */
  1070. /*    Report how to use program                                       */
  1071. /*--------------------------------------------------------------------*/
  1072.  
  1073. static void usage( void )
  1074. {
  1075.    fputs("Usage:\tuustat\t[-m | -q | -a] [-u userid | all ] [-s system | all] [-x debug]\n\
  1076. \t\t[-k | -r ] jobid [-x debug]\n\
  1077. \t\t[-P system | all] [-x debug]\n\n\
  1078. \tDefault is to display jobs queued by current user\n\
  1079. \t-a\t\tDisplays all jobs for all users\n\
  1080. \t-k jobid\tKills job \"jobid\"\n\
  1081. \t-m\t\tDisplays accessability of known systems\n\
  1082. \t-q\t\tDisplays summary of queues for systems with work\n\
  1083. \t-r jobid\tRefreshes timestamps on job \"jobid\"\n\
  1084. \t-s system\tRestricts output to system (Ignored by -k -P -r)\n\
  1085. \t-u userid\tRestricts output to userid (Ignored by -k -m -P -q -r)\n\
  1086. \t-P system\tQueues dummy job for system \"system\" to force poll\n\
  1087. \t-x debuglevel",
  1088.             stdout );
  1089.    exit(1);
  1090. } /* usage */
  1091.